﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Unscrambler.Views;
using System.Windows.Media.Animation;
using System.Windows.Controls;
using System.Windows;
using Unscrambler.Controls;
using System.Windows.Media;
using System.Windows.Input;
using Unscrambler.Constants;

namespace Unscrambler.Helpers
{
    public class TilePositioner : TileHelperBase
    {
        private IGameboardView _gameboard;
        private Random rand = new Random(DateTime.Now.Millisecond);

        public TilePositioner(IGameboardView gameboard)
        {
            if (gameboard == null)
            {
                throw new ArgumentNullException("Gameboard cannot be null");
            }

            _gameboard = gameboard;
        }

        public void PositionAllTiles(string word)
        {
            if (string.IsNullOrEmpty(word))
            {
                throw new ArgumentNullException("word cannot be null or empty");
            }
            List<double> leftValues = new List<double>();
            word.ToList().ForEach(x => AddTileToRandomLocation(x));
            FadeInTiles(_gameboard.ScramblePanel.Children);
        }

        private void AddTileToRandomLocation(char letter)
        {
            LetterTile tile = new LetterTile();
            tile.Letter = letter;
            SetInitialPositionForElement(tile);
            _gameboard.ScramblePanel.Children.Add(tile);
            tile.Opacity = 0.0;
            tile.PreviewMouseDoubleClick += new MouseButtonEventHandler(tile_PreviewMouseDoubleClick);
        }

        void tile_PreviewMouseDoubleClick(object sender, MouseButtonEventArgs e)
        {
            UIElement element = sender as UIElement;
            if (element != null)
            {
                RotateTransform rotateTransform = GetRotateTransformFromUIElement(element);
                rotateTransform.Angle = 0;
            }
        }

        private static void FadeInTiles(UIElementCollection tiles)
        {
            Storyboard fadeInStoryboard = new Storyboard();
            TimeSpan timeSpan = new TimeSpan(0, 0, 0, 0, 300);

            foreach (UIElement element in tiles)
            {
                if (element is LetterTile)
                {
                    DoubleAnimation fadeIn = new DoubleAnimation(1, new Duration(timeSpan));
                    fadeIn.SetValue(Storyboard.TargetPropertyProperty, new PropertyPath("Opacity"));
                    fadeIn.SetValue(Storyboard.TargetProperty, element);
                    fadeInStoryboard.Children.Add(fadeIn);
                }
            }

            fadeInStoryboard.Begin();
        }

        private void SetInitialPositionForElement(UIElement element)
        {
            TransformGroup tGroup = new TransformGroup();
            tGroup.Children.Add(CreateRandomRotateTransform());
            tGroup.Children.Add(CreateRandomTranslateTransform());
            element.RenderTransform = tGroup;
        }

        private TranslateTransform CreateRandomTranslateTransform()
        {
            double randomXValue = rand.NextDouble() * (_gameboard.ActualWidth - SizeConstants.LetterTileSideLength);
            double randomYValue = rand.NextDouble() * (_gameboard.ActualHeight - SizeConstants.LetterTileSideLength);

            if (randomYValue <= _gameboard.AnswerPanel.Height)
            {
                randomYValue += _gameboard.AnswerPanel.Height;
            }

            TranslateTransform translateTransform = new TranslateTransform(randomXValue, randomYValue);
            return translateTransform;
        }

        private RotateTransform CreateRandomRotateTransform()
        {
            RotateTransform rotateTransform;
            //only rotate it about 1/4 of the time, if all the letters are rotated it's annoying
            if (rand.NextDouble() >= .75)
            {
                rotateTransform = new RotateTransform(Convert.ToDouble(rand.Next(360)));
                rotateTransform.CenterX = SizeConstants.LetterTileSideLength / 2;
                rotateTransform.CenterY = SizeConstants.LetterTileSideLength / 2;
            }
            else
            {
                rotateTransform = new RotateTransform(0);
            }
            return rotateTransform;
        }
    }
}
